package com.wpx.batch.log;

import com.wpx.batch.WpxBatchUtils;

import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.util.Set;

public class ExecuteLogger {

    public enum Level{
        debug,info,err;
    }
    private final Level level;
    
    private final long executeId;

    private final Set<ILogHandler> logHandlers;

    public ExecuteLogger(Level level, long executeId, Set<ILogHandler> logHandlers){
        this.level = level;
        this.executeId = executeId;
        this.logHandlers = logHandlers;
    }

    public void debug(String log, Object... params){
        if(!isHandelLevel(Level.debug)) return;
        this.handle(log, null, params);
    }

    public void info(String log, Object... params){
        if(!isHandelLevel(Level.info)) return;
        this.handle(log, null, params);
    }

    public void error(String log, Throwable e, Object... params){
        this.handle(log, e, params);
    }

    private void handle(String log, Throwable e, Object... params){
        log = format(log, params);

        if(e != null){
            ByteArrayOutputStream bout = new ByteArrayOutputStream();
            e.printStackTrace(new PrintStream(bout));
            log = log + "\n" + new String(bout.toByteArray());
        }

        for (ILogHandler logHandler : this.logHandlers) {
            logHandler.handle(this.executeId, log);
        }
    }


    private boolean isHandelLevel(Level flevel){
        switch (this.level){
            case debug: return true;
            case info: {
                if(Level.debug == flevel) return false;
                return true;
            }
            case err: {
                if(Level.debug == flevel) return false;
                if(Level.info == flevel) return false;
            }
        }
        return true;
    }

    private String format(String log, Object... paras){
        if(WpxBatchUtils.isEmpty(log) || WpxBatchUtils.isEmpty(paras))
            return log;
        StringBuffer sb = new StringBuffer(log);
        int index = 0;
        int i = 0;
        while ((index = sb.indexOf("{}", index)) != -1) {
            if (i >= paras.length) break;
            Object para = paras[i];
            sb.replace(index, index + 2, para == null ? "null" : para.toString());
            i++;
        }

        return sb.toString();
    }
}
